<script setup lang="ts">
import keymaster from 'keymaster'
import {computed, onBeforeUnmount, onMounted, provide, ref} from 'vue'
import {useRoute} from 'vue-router'
import {ElMessage} from 'element-plus'

import {accessRecordsDB, hotDB, movieDB} from '@/data/lowdb.ts'
import {loadVideos} from '@/data/movie'
import {AccessRecord, DreamVideo, Movie} from '@/data/Dream'
import {sortByAccessRecords} from '@/data/access_records'

import VideoOnePicture from '@/pages/dreamVideo/components/video-one-picture.vue'
import VideoSomePictures from '@/pages/dreamVideo/components/video-some-pictures.vue'
import VideoThreePictures from '@/pages/dreamVideo/components/video-three-pictures.vue'
import ImageContextMenu from '@/components/ImageContextMenu.vue'
import SearchInput from '@/components/search-input.vue'
import {openVideoDefault} from '@/utils/utils.ts'

const route = useRoute()
const name = <string>route.query.name
const year = parseInt(<string>route.query.year)

const videoAccessRecords = ref<Map<string, AccessRecord>>()
provide('videoAccessRecords', videoAccessRecords)

const movie = ref<Movie>({
  name: '',
  year: 0,
  star: '',
  images: [],
  dreamVideos: [],
  duration: 0,
  durationF: '',
  size: 0,
  sizeF: ''
})
provide('movie', movie)

// 视频排序
const sortByDefault = ref(true)
onMounted(() => {
  // s -> Sort
  keymaster('s', function () {
    sortByDefault.value = !sortByDefault.value
    ElMessage(sortByDefault.value ? 'sort by default' : 'sort by access records')
    return false
  })
})
onBeforeUnmount(() => {
  keymaster.unbind('s')
})
// 数据库里所有的 dreamVideos，排访问时间逆序
const dreamVideos = computed(() => {
  const videos = movie.value.dreamVideos
  if (sortByDefault.value) {
    return videos
  }
  return videos.slice().sort((a, b) => {
    return sortByAccessRecords(
        videoAccessRecords.value.get(a.video),
        videoAccessRecords.value.get(b.video)
    )
  })
})
// 3 张图片
const dreamVideos3 = computed(() => {
  return dreamVideos.value.filter((v) => v.images.length === 3)
})
// 3 张以上图片
const dreamVideosManyImg = computed(() => {
  return dreamVideos.value.filter((v) => v.images.length > 3)
})
// 1、2 张图片
const dreamVideosFewImg = computed(() => {
  return dreamVideos.value.filter((v) => v.images.length === 1 || v.images.length === 2)
})
// 1 张以上图片
const dreamVideosOneImg = computed(() => {
  return dreamVideos.value.filter((v) => v.images.length > 0)
})
// 没有图片
const dreamVideosNoImg = computed(() => {
  return dreamVideos.value.filter((v) => v.images.length === 0)
})

function loadDataFromDB() {
  videoAccessRecords.value = new Map<string, AccessRecord>(Object.entries(
      accessRecordsDB.get('videoAccessRecords').value())
  )

  movie.value = movieDB.read().find({name, year}).value()
}

onMounted(() => {
  loadDataFromDB()
  keymaster('f5', function () {
    refreshData()
    return false
  })
})

onBeforeUnmount(() => {
  keymaster.unbind('f5')
})

function openFile(file: string) {
    openVideoDefault(movie.value, file, videoAccessRecords.value)
}

async function refreshData() {
  ElMessage('刷新数据开始')
  await loadVideos(name, year)
  loadDataFromDB()
  ElMessage('刷新数据结束')
}

// 搜索
const elementRefs = new Map<string, HTMLElement>

const setElementRefs = (el: HTMLElement, video: DreamVideo) => {
  if (el) {
    elementRefs.set(video.name, el)
  }
}

// 右键弹出菜单
const contextMenuRef = ref<InstanceType<typeof ImageContextMenu>>()

provide('hots', hotDB.read().value())

// 切换显示一张图片和全部图片
const showOnePicture = ref(false)
onMounted(() => {
  // a -> A picture
  keymaster('a', function () {
    showOnePicture.value = !showOnePicture.value
    ElMessage(showOnePicture.value ? 'show a picture' : 'show all pictures')
    return false
  })
})
onBeforeUnmount(() => {
  keymaster.unbind('a')
})
</script>

<template>
  <image-context-menu ref="contextMenuRef"
                      :video-access-records="videoAccessRecords"
  />

  <search-input :view-elements="elementRefs"/>

  <div v-if="showOnePicture">
    <div class="dreamVideosFewImg" v-if="dreamVideosOneImg.length > 0">
      <div class="video" v-for="video in dreamVideosOneImg" :key="video.video"
           @contextmenu.prevent="openFile(video.video)"
           :ref="(el) => setElementRefs(<HTMLElement>el, video)">

        <video-one-picture :video="video"/>
      </div>
    </div>
  </div>

  <div v-else id="dreamVideoDiv">

    <div class="video-container">
      <div class="video" v-for="video in dreamVideos3" :key="video.video"
           :ref="(el) => setElementRefs(<HTMLElement>el, video)">

        <video-three-pictures :video="video"
                            :context-menu="contextMenuRef"
        />
      </div>
    </div>

    <hr v-if="dreamVideos3.length > 0 && (dreamVideosManyImg.length > 0 || dreamVideosFewImg.length > 0)">

    <div class="dreamVideosManyImg" v-if="dreamVideosManyImg.length > 0">
      <div class="video" v-for="video in dreamVideosManyImg" :key="video.video"
           :ref="(el) => setElementRefs(<HTMLElement>el, video)">

        <video-some-pictures :video="video"
                         :context-menu="contextMenuRef"
        />
      </div>
    </div>

    <hr v-if="dreamVideosManyImg.length > 0 && dreamVideosFewImg.length > 0">

    <div class="dreamVideosFewImg" v-if="dreamVideosFewImg.length > 0">
      <div class="video" v-for="video in dreamVideosFewImg" :key="video.video"
           :ref="(el) => setElementRefs(<HTMLElement>el, video)">

        <video-some-pictures :video="video"
                         :context-menu="contextMenuRef"
        />
      </div>
    </div>
  </div>

  <div class="refreshButton">
    <el-button @click='refreshData' type='primary' icon='Refresh' size="large" circle plain/>
  </div>
  <div class="dreamVideosNoImg">
    <p v-for="video in dreamVideosNoImg" :key="video.video"
       :ref="(el) => setElementRefs(<HTMLElement>el, video)"
       @contextmenu.prevent="openFile(video.video)">
        <span class="text">
          <span>{{ video.name }}</span>
          <span style="font-size: 11px;color: #a3a2a2; margin-left: 10px">{{ video.durationF }} {{ video.sizeF }}</span>
        </span>
    </p>
  </div>
</template>

<style lang="stylus" scoped>
.video
  background white
  border-radius 5px
  border 2px solid #f4f4f4
  &:hover
    border 2px solid #00BE9A;

.dreamVideosManyImg, .dreamVideosFewImg
  margin-bottom 10px
  .video
    margin-bottom: 15px
.dreamVideosFewImg
  display: flex
  flex-wrap: wrap
  justify-content: space-around


.video-container
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  .video
    margin-bottom: 5px;


.dreamVideosNoImg
  font-size: 16px;
  margin: 20px auto 0;
  width: max-content;
.refreshButton
  width: max-content
  margin: 10px auto 0
hr
  margin-bottom: 20px
  border: none;
  height: 0.5px;
  background: #c8c4c4;
</style>